#!/bin/bash

set -o errexit

test_dir=$(realpath $(dirname $0))
deploy_dir=$(realpath $(dirname $0)/../../deploy)
. ${test_dir}/../functions

set_debug

function stop_cluster() {
	local cluster_name=$1
	local max_wait_time=${2:-120}

	local passed_time=0
	local sleep_time=1
	kubectl_bin patch pxc ${cluster_name} --type json -p='[{"op":"add","path":"/spec/pause","value":true}]'
	set +x
	echo -n 'Waiting for cluster stop'
	until [[ $(kubectl_bin get pxc ${cluster_name} -o jsonpath='{.status.ready}') -le 0 ]]; do
		echo -n .
		let passed_time="${passed_time}+${sleep_time}"
		sleep ${sleep_time}
		if [[ ${passed_time} -gt ${max_wait_time} ]]; then
			echo "We've been waiting for cluster stop for too long. Exiting..."
			exit 1
		fi
	done
	echo
	set -x
}

function start_cluster() {
	local cluster_name=$1

	kubectl_bin patch pxc ${cluster_name} --type json -p='[{"op":"add","path":"/spec/pause","value":false}]'
	wait_cluster_consistency \
		${cluster_name} \
		$(kubectl_bin get pxc/${cluster_name} -o jsonpath={.spec.pxc.size}) \
		$(kubectl_bin get pxc/${cluster_name} -o jsonpath={.spec.$(get_proxy_engine ${cluster_name}).size})
}

function main() {
	create_infra "${namespace}"

	cluster="$(yq eval '.metadata.name' ${deploy_dir}/cr.yaml)"

	kubectl_bin apply -f ${deploy_dir}/secrets.yaml
	kubectl_bin apply -f ${conf_dir}/client.yml
	kubectl_bin apply -f ${conf_dir}/secrets.yml
	kubectl_bin apply -f ${deploy_dir}/cr.yaml

	pxc_size=$(kubectl_bin get pxc/${cluster} -o jsonpath={.spec.pxc.size})
	proxy_size=$(kubectl_bin get pxc/${cluster} -o jsonpath={.spec.$(get_proxy_engine ${cluster}).size})

	wait_for_running "$(get_proxy ${cluster})" ${proxy_size}
	wait_for_running "${cluster}-pxc" ${pxc_size}

	desc 'check if service and statefulset created with expected config'
	compare_kubectl statefulset/${cluster}-pxc
	compare_kubectl statefulset/$(get_proxy ${cluster})
	compare_kubectl service/${cluster}-pxc
	compare_kubectl service/${cluster}-pxc-unready
	compare_kubectl service/$(get_proxy ${cluster})
	compare_kubectl service/$(get_proxy ${cluster})-replicas

	desc 'install PMM Server'
	deploy_pmm_server
	sleep 120
	ADMIN_PASSWORD=$(kubectl_bin exec monitoring-0 -- bash -c "printenv | grep ADMIN_PASSWORD | cut -d '=' -f2")
	MONITORING_ENDPOINT=$(get_service_endpoint monitoring-service)
	API_KEY=$(curl --insecure -X POST -H "Content-Type: application/json" -d '{"name":"operator", "role": "Admin"}' "https://admin:$ADMIN_PASSWORD@$MONITORING_ENDPOINT/graph/api/auth/keys" | jq .key)

	kubectl_bin patch secret ${cluster}-secrets --type merge --patch '{"stringData": {"pmmserverkey": '$API_KEY'}}'

	sleep 20
	desc "enable pmm"
	kubectl_bin patch pxc/${cluster} --type=merge --patch '{
			"spec": {"pmm":{"enabled":true}}
		}'
	sleep 120
	# since pxc cluster won't work without pmm server running consistency check would be enough
	wait_cluster_consistency ${cluster} ${pxc_size} ${proxy_size}

	desc "disable pmm"
	kubectl_bin patch pxc/${cluster} --type=merge --patch '{
			"spec": {"pmm":{"enabled":false}}
		}'
	sleep 120
	helm uninstall monitoring
	wait_cluster_consistency ${cluster} ${pxc_size} ${proxy_size}

	desc 'write data directly, read from all'
	run_mysql \
		"CREATE DATABASE IF NOT EXISTS myApp; use myApp; CREATE TABLE IF NOT EXISTS myApp (id int PRIMARY KEY);" \
		"-h ${cluster}-pxc-2.${cluster}-pxc -uroot -proot_password"
	run_mysql \
		'INSERT myApp.myApp (id) VALUES (100501)' \
		"-h ${cluster}-pxc-2.${cluster}-pxc -uroot -proot_password"
	sleep 20

	for i in $(seq 0 $((pxc_size - 1))); do
		compare_mysql_cmd "select-2" "SELECT * from myApp.myApp;" "-h ${cluster}-pxc-${i}.${cluster}-pxc -uroot -proot_password"
	done
	desc "stop cluster"
	stop_cluster ${cluster}
	desc "start cluster"
	start_cluster ${cluster}
	wait_cluster_consistency ${cluster} ${pxc_size} ${proxy_size}

	desc "compare data"
	for i in $(seq 0 $((pxc_size - 1))); do
		compare_mysql_cmd "select-2" "SELECT * from myApp.myApp;" "-h ${cluster}-pxc-${i}.${cluster}-pxc -uroot -proot_password"
	done

	kubectl_bin delete -f ${deploy_dir}/cr.yaml
	desc "run cr-minimal"
	cluster="$(yq eval '.metadata.name' ${deploy_dir}/cr-minimal.yaml)"
	kubectl_bin apply -f ${deploy_dir}/cr-minimal.yaml

	pxc_size=$(kubectl_bin get pxc/${cluster} -o jsonpath={.spec.pxc.size})
	proxy_size=$(kubectl_bin get pxc/${cluster} -o jsonpath={.spec.$(get_proxy_engine ${cluster}).size})

	wait_for_running "$(get_proxy ${cluster})" ${proxy_size}
	wait_for_running "${cluster}-pxc" ${pxc_size}

	desc 'check if service and statefulset created with expected config'
	compare_kubectl statefulset/${cluster}-pxc
	compare_kubectl statefulset/$(get_proxy ${cluster})
	compare_kubectl service/${cluster}-pxc
	compare_kubectl service/${cluster}-pxc-unready
	compare_kubectl service/$(get_proxy ${cluster})
	compare_kubectl service/$(get_proxy ${cluster})-replicas

	destroy $namespace
	desc "test passed"
}

main
